package com.tonghl.juc.lock_study.code;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created by tonghl
 * 多个线程同时读一个资源类是没有任何问题的，所以为了满足并发量，读取共享资源类应该可以同时进行
 * 但是
 * 如果有一个线程想去写共享资源类，就不应该在有其他的线程可以对该资源类进行读或者写
 *
 * 小总结：
 *      读------读能共存
 *      读------写不能共存
 *      写------写不能共存
 *
 *      写操作：原子+独占 ，整个过程必须是一个完整的统一体不可分割
 */
class  Mycache{//资源类

    private  volatile Map<String,Object> map=new HashMap<>();
    private ReentrantReadWriteLock rwLock=new ReentrantReadWriteLock();
    //private Lock lock=new ReentrantLock();


   /* public void put(String key,Object value) {
        System.out.println(Thread.currentThread().getName()+"\t 正在写入："+key);
        try{ TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){e.printStackTrace();}
        map.put(key,value);
        System.out.println(Thread.currentThread().getName()+"\t 写入完成：");
    }*/

    public void put(String key,Object value) {
        rwLock.writeLock().lock();

        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在写入："+key);
            try{ TimeUnit.MILLISECONDS.sleep(300); }catch (InterruptedException e){e.printStackTrace();}
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"\t 写入完成：");
        }catch (Exception e){
          e.printStackTrace();
        }finally {
            rwLock.writeLock().unlock();
        }

    }

   /* public void get(int key) {
        System.out.println(Thread.currentThread().getName()+"\t 正在读取："+key);
        try{ TimeUnit.SECONDS.sleep(2); }catch (InterruptedException e){e.printStackTrace();}
        Object obj= map.get(key);
        System.out.println(Thread.currentThread().getName()+"\t 读取完成：");
    }*/

    public void get(int key) {
       rwLock.readLock().lock();

        try {
            System.out.println(Thread.currentThread().getName()+"\t 正在读取："+key);
            try{ TimeUnit.SECONDS.sleep(2); }catch (InterruptedException e){e.printStackTrace();}
            Object obj= map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t 读取完成："+obj);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            rwLock.readLock().unlock();
        }
    }
}


public class ReadWriteLockDemo {

    public static void main(String[] args) {
        Mycache mycache = new Mycache();
          for (int i = 1; i <=5 ; i++)
                  {
                      int a = i;
                      new Thread(()->
                      {
                      final  int temp= a;
                      mycache.put(temp+"",temp+"");
                      },String.valueOf(i)).start();
                  }


                        for (int i = 1; i <=5 ; i++)
                        {
                            int a = i;
                            new Thread(()->
                            {
                                final  int temp= a;
                                mycache.get(a);
                            },String.valueOf(i)).start();
                        }
    }
}
